////
//// Created by HP on 2025/11/12.
////
//
#ifndef FLIGHTSERVER_EMAILSENDER_H
#define FLIGHTSERVER_EMAILSENDER_H
//
#include <string>
#include <initializer_list>
#include <memory>
#include <utility>
#include <iostream>
#include <QtNetwork/QSslSocket>
#include <QtCore/QByteArray>
#include <QtCore/QElapsedTimer>

class EmailSender {
private:
    std::unique_ptr<QSslSocket> socket;
    std::string smtp_host;    // SMTP 服务器地址（如 smtp.qq.com）
    std::string smtp_port;    // SMTP 端口（如 465 用于 SSL）
    std::string smtp_user;    // 邮箱账号
    std::string smtp_password;// 邮箱授权码（非登录密码）
    std::string smtp_from;    // 发件人邮箱

    static EmailSender* instance;

public:
    // 构造函数：从 Config 读取配置
    EmailSender(std::string smtp_host, std::string smtp_port, std::string smtp_user, std::string smtp_password, std::string smtp_from): socket(nullptr), smtp_host(std::move(smtp_host)), smtp_port(std::move(smtp_port)), smtp_user(std::move(smtp_user)), smtp_password(std::move(smtp_password)), smtp_from(std::move(smtp_from)) {

    }

/**
 * @brief 初始化EmailSender实例
 * @return 初始化是否成功
 *
 * 该函数用于初始化EmailSender实例，确保系统中只存在一个EmailSender实例。
 * 它会检查是否已存在实例，如果存在则初始化失败；否则创建新的QSslSocket并设置对等体验证模式。
 */
    bool init() {
        // 检查是否已存在实例，且当前对象不是已存在的实例
        if (instance != nullptr && instance != this) {
            std::cerr << "Only one instance of EmailSender is allowed" << std::endl;
            return false;
        }
        // 创建新的QSslSocket对象
        socket = std::make_unique<QSslSocket>();
        // 对于某些 SMTP 服务器，可能需要更宽松的验证模式
        socket->setPeerVerifyMode(QSslSocket::VerifyNone);
        // 设置支持的协议版本
        socket->setProtocol(QSsl::TlsV1_2OrLater);
        // 将当前对象设置为实例
        instance = this;
        return true;
    }

    ~EmailSender() {
        if (socket) {
            if (socket->isOpen()) {
                socket->disconnectFromHost();
                socket->waitForDisconnected(3000);
            }
        }
    }

    /**
     * 发送验证码邮件
     * @param to 收件人邮箱
     * @param code 验证码
     * @return 发送成功返回 true
     */
    bool sendVerificationCode(const std::string& to, const std::string& code);

    static EmailSender* getInstance() {
        return instance;
    }

private:
    bool ensureSocket();
    bool sendCommand(const QString& command, std::initializer_list<int> expectCodes, int timeoutMs = 10000);
    bool sendCommand(const QString& command, int expectCode, int timeoutMs = 10000) {
        return sendCommand(command, {expectCode}, timeoutMs);
    }
    int readResponse(QByteArray& response, int timeoutMs);
};
//
#endif //FLIGHTSERVER_EMAILSENDER_H
